/*
 *  Based on arch/arm/include/asm/mach/pci.h
 *
 *  Copyright (C) 2000 Russell King
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#ifndef __ASM_PCIBIOS_H
#define __ASM_PCIBIOS_H

#include <linux/ioport.h>

struct pci_sys_data;
struct pci_ops;
struct pci_bus;
struct device;

struct hw_pci {
#ifdef CONFIG_PCI_DOMAINS
	int domain;
#endif
	struct pci_ops *ops;
	int nr_controllers;
	void **private_data;
	int (*setup) (int nr, struct pci_sys_data *);
	struct pci_bus *(*scan) (int nr, struct pci_sys_data *);
	void (*preinit) (void);
	void (*postinit) (void);
	 u8(*swizzle) (struct pci_dev *dev, u8 *pin);
	int (*map_irq) (const struct pci_dev *dev, u8 slot, u8 pin);
	 resource_size_t(*align_resource) (struct pci_dev *dev,
					   const struct resource *res,
					   resource_size_t start,
					   resource_size_t size,
					   resource_size_t align);
	void (*add_bus) (struct pci_bus *bus);
	void (*remove_bus) (struct pci_bus *bus);
};

/*
 * Per-controller structure
 */
struct pci_sys_data {
#ifdef CONFIG_PCI_DOMAINS
	int domain;
#endif
	struct list_head node;
	int busnr;		/* primary bus number                   */
	u64 mem_offset;		/* bus->cpu memory mapping offset       */
	unsigned long io_offset;	/* bus->cpu IO mapping offset   */
	struct pci_bus *bus;	/* PCI bus                              */
	struct list_head resources;	/* root bus resources (apertures) */
	struct resource io_res;
	char io_res_name[12];
	/* Bridge swizzling                     */
	 u8(*swizzle) (struct pci_dev *, u8 *);
	/* IRQ mapping                          */
	int (*map_irq) (const struct pci_dev *, u8, u8);
	/* Resource alignement requirements     */
	 resource_size_t(*align_resource) (struct pci_dev *dev,
					   const struct resource *res,
					   resource_size_t start,
					   resource_size_t size,
					   resource_size_t align);
	void (*add_bus) (struct pci_bus *bus);
	void (*remove_bus) (struct pci_bus *bus);
	void *private_data;	/* platform controller private data     */
};

/*
 * Call this with your hw_pci struct to initialise the PCI system.
 */
void pci_common_init_dev(struct device *, struct hw_pci *);

/*
 * Compatibility wrapper for older platforms that do not care about
 * passing the parent device.
 */
static inline void pci_common_init(struct hw_pci *hw)
{
	pci_common_init_dev(NULL, hw);
}

/*
 * Setup early fixed I/O mapping.
 */
#if defined(CONFIG_PCI)
extern void pci_map_io_early(unsigned long pfn);
#else
static inline void pci_map_io_early(unsigned long pfn)
{
}
#endif

#endif /* __ASM_PCIBIOS_H */